﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HotelManager.BusinessLogic.Abstract;
using HotelManager.DataAccess;
using HotelManager.DataAccess.Model;
using HotelManager.WebUI.Models;
using PagedList;

namespace HotelManager.WebUI.Controllers
{
    public class SearchController : Controller
    {
        private IHotelService _hotelService;

        private const int PageSize = 6;

        public SearchController(IHotelService hotelService)
        {
            _hotelService = hotelService;
        }

        public ActionResult SearchHotel(SearchModel model)
        {
            // Save model
            if (ModelState.IsValid)
            {
                Session["search"] = model;
            }
            else
            {
                model = (SearchModel) Session["search"];
            }

            // Search hotels
            List<Hotel> list = _hotelService.SearchHotel(model);

            // Create info model
            SearchInfoModel info = new SearchInfoModel
                                       {
                                           Hotels = list,
                                           CheckInTime = model.CheckInTime,
                                           CheckOutTime = model.CheckOutTime
                                       };

            // Save to session
            Session["info"] = info;

            ViewBag.Options = _hotelService.GetAllOptions();

            Session["pagedList"] = list;

            IPagedList<Hotel> result = list.OrderBy(x => x.Name).ToPagedList(1, PageSize);
            return View(result);
        }

        public ActionResult Filter(int[] price,int starinput,  int[] selectedOption, SearchInfoModel info)
        {
            var refinement = new RefinementModel();

            List<Hotel> list;
            //Filter price
            if (price != null)
            {
                list = new List<Hotel>();
                foreach (var i in price)
                {
                    switch (i)
                    {
                        case 0:
                            list.AddRange(from hotel in info.Hotels from room in hotel.RoomTypes where room.Price < 50 select hotel);
                            break;
                        case 1:
                            list.AddRange(from hotel in info.Hotels from room in hotel.RoomTypes where room.Price > 49 && room.Price < 100 select hotel);
                            break;
                        case 2:
                            list.AddRange(from hotel in info.Hotels from room in hotel.RoomTypes where room.Price > 99 && room.Price < 200 select hotel);
                            break;
                        case 3:
                            list.AddRange(from hotel in info.Hotels from room in hotel.RoomTypes where room.Price > 200 select hotel);
                            break;
                        default:
                            list = info.Hotels;
                            break;
                    }
                }
            }
            else
            {
                list = info.Hotels;
            }
            
            list = list.Distinct(new HotelComparer()).ToList();

            //Filt star
            if (starinput != 0)
            {
                list = list.Where(x => x.Stars >= starinput).ToList();
            }

            var hotels = list;
            //Filt facilities
            if (selectedOption != null)
            {
                hotels = (from hotel in list
                              from option in hotel.HotelOptions
                              where selectedOption.Contains(option.OptionId)
                              select hotel)
                          .Distinct(new HotelComparer())
                          .ToList();
            }        

            refinement.Hotels = hotels;

            Session["pagedList"] = hotels;

            IPagedList<Hotel> result = hotels.OrderBy(x => x.Name).ToPagedList(1, PageSize);
            return PartialView("Hotels", result);
        }

        public PartialViewResult PagedResult(int page)
        {
            List<Hotel> hotels = (List<Hotel>) Session["pagedList"];
            IPagedList<Hotel> result = hotels.OrderBy(x => x.Name).ToPagedList(page, PageSize);
            return PartialView("Hotels", result);
        }
    }
}
